package com.c2soft.ncmxSocket;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;

import com.c2soft.ncmxSocket.*;

/**
 * Hello world!
 * 
 */
public class MockSocketServer {

	static Map<String, String> tokenIdSymbolMap;
	static {
		try {
			tokenIdSymbolMap = readMCXContract();
		} catch (IOException e1) {

			e1.printStackTrace();
		}
	}

	// static ServerSocket variable
	private ServerSocket server;
	// socket server port on which it will listen
	private int port;
	private boolean isStopped;

	public MockSocketServer(int port, boolean isStopped) throws IOException {
		super();
		this.port = port;
		this.server = new ServerSocket(port);
		this.isStopped = isStopped;
	}

	public static void main(String[] args) throws IOException,
			ClassNotFoundException {

		MockSocketServer mockSocketServer = new MockSocketServer(9140, false);
		// keep listens indefinitely until receives 'exit' call or program
		// terminates

		while (!mockSocketServer.isStopped) {
			System.out.println("Waiting for client request");

			// creating socket and waiting for client connection
			Socket socket = mockSocketServer.server.accept();

			// read from socket to ObjectInputStream object
			ObjectInputStream ois = new ObjectInputStream(
					socket.getInputStream());

			// convert ObjectInputStream object to String
			String message = (String) ois.readObject();
			System.out.println("Message Received: " + message);

			// create ObjectOutputStream object
			ObjectOutputStream oos = new ObjectOutputStream(
					socket.getOutputStream());
			// write object to Socket

			// oos.writeObject("Hi Client "+message);

			 oos.writeObject(mockSocketServer.createQuotePackets());

			oos = writeMockResponse(oos);

			// close resources
			ois.close();
			oos.close();
			socket.close();
			// terminate the server if client sends exit request
			if (message.equalsIgnoreCase("exit"))
				break;
		}
		System.out.println("Shutting down Socket server!!");
		// close the ServerSocket object
		mockSocketServer.server.close();

	}

	private static ObjectOutputStream writeMockResponse(ObjectOutputStream oos) {

		return null;
	}

	private byte[] createQuotePackets() {
		byte[] case1 = shortToByteArray((short) 50);
		byte[] noOfPackets = shortToByteArray((short) 5);

		QuoteData quoteData1 = new QuoteData((short) 5, 206911,
				tokenIdSymbolMap.get("206911"), randomIntGenerator(),
				randomIntGenerator(), randomIntGenerator(),
				randomIntGenerator(), randomIntGenerator(),
				randomIntGenerator(), randomIntGenerator(),
				randomIntGenerator(), randomIntGenerator(),
				randomIntGenerator(), randomIntGenerator(),
				randomDoubleGenerator(), randomDoubleGenerator(),
				randomDoubleGenerator(), randomDoubleGenerator());
		QuoteData quoteData2 = new QuoteData((short) 5, 206994,
				tokenIdSymbolMap.get("206994"), randomIntGenerator(),
				randomIntGenerator(), randomIntGenerator(),
				randomIntGenerator(), randomIntGenerator(),
				randomIntGenerator(), randomIntGenerator(),
				randomIntGenerator(), randomIntGenerator(),
				randomIntGenerator(), randomIntGenerator(),
				randomDoubleGenerator(), randomDoubleGenerator(),
				randomDoubleGenerator(), randomDoubleGenerator());
		QuoteData quoteData3 = new QuoteData((short) 5, 206870,
				tokenIdSymbolMap.get("206870"), randomIntGenerator(),
				randomIntGenerator(), randomIntGenerator(),
				randomIntGenerator(), randomIntGenerator(),
				randomIntGenerator(), randomIntGenerator(),
				randomIntGenerator(), randomIntGenerator(),
				randomIntGenerator(), randomIntGenerator(),
				randomDoubleGenerator(), randomDoubleGenerator(),
				randomDoubleGenerator(), randomDoubleGenerator());
		QuoteData quoteData4 = new QuoteData((short) 5, 206860,
				tokenIdSymbolMap.get("206860"), randomIntGenerator(),
				randomIntGenerator(), randomIntGenerator(),
				randomIntGenerator(), randomIntGenerator(),
				randomIntGenerator(), randomIntGenerator(),
				randomIntGenerator(), randomIntGenerator(),
				randomIntGenerator(), randomIntGenerator(),
				randomDoubleGenerator(), randomDoubleGenerator(),
				randomDoubleGenerator(), randomDoubleGenerator());
		QuoteData quoteData5 = new QuoteData((short) 5, 206940,
				tokenIdSymbolMap.get("206940"), randomIntGenerator(),
				randomIntGenerator(), randomIntGenerator(),
				randomIntGenerator(), randomIntGenerator(),
				randomIntGenerator(), randomIntGenerator(),
				randomIntGenerator(), randomIntGenerator(),
				randomIntGenerator(), randomIntGenerator(),
				randomDoubleGenerator(), randomDoubleGenerator(),
				randomDoubleGenerator(), randomDoubleGenerator());

		return concat(case1, noOfPackets, quoteData1.toByteArray(),
				quoteData2.toByteArray(), quoteData3.toByteArray(),
				quoteData4.toByteArray(), quoteData5.toByteArray());

	}

	public byte[] shortToByteArray(short x) {
		return ByteBuffer.allocate(2).order(ByteOrder.LITTLE_ENDIAN)
				.putShort(x).array();
	}

	private byte[] concat(byte[]... arrays) {
		int lengh = 0;
		for (byte[] array : arrays) {
			lengh += array.length;
		}
		byte[] result = new byte[lengh];
		int pos = 0;
		for (byte[] array : arrays) {
			for (byte element : array) {
				result[pos] = element;
				pos++;
			}
		}
		return result;
	}

	private static Map<String, String> readMCXContract() throws IOException {
		File file = new File("MCX.txt");
		Map<String, String> tokenIdSymbolMap = new HashMap<String, String>();
		// String string = FileUtils.readFileToString(file);
		List<String> lines = FileUtils.readLines(file);
		for (String line : lines) {
			if (StringUtils.isNotBlank(line)) {
				// System.out.println("line:" + line);
				String[] strArray = StringUtils.split(line, ",");
				tokenIdSymbolMap.put(strArray[1], strArray[2]);
			}
		}

		return tokenIdSymbolMap;

	}

	private short randomShortGenerator() {
		Random random = new Random();
		// short s = (short) r.nextInt(1 << 15);
		// System.out.println(s);

		return (short) (random.nextInt(10 - 1 + 1) + 1);
	}

	private int randomIntGenerator() {
		Random r = new Random();
		int output = r.nextInt(90000 - 10000) + 10000;
		return output;
	}

	private double randomDoubleGenerator() {
		double diff = 8000D - 500D;
		return 500 + Math.random() * diff;
	}

}
